#ifndef _QUEUE_ITEM_HPP_20120708
#define _QUEUE_ITEM_HPP_20120708

#include "timer.hpp"
#include "http_cmd.hpp"

using namespace mina;

class RequestType
{
	public :
		enum
		{
			T_UNKNOWN               = 0,
			T_TENCENT_GET_USER_INFO = 1,
		};

	public :
		RequestType(int16_t type = T_UNKNOWN) : _type(type) {}

		const char * to_string() const
		{
			return to_string(_type);
		}

		static const char * to_string(int16_t type) 
		{
#undef CASE
#define CASE(type) \
			case type: \
					   { \
						   return #type; \
					   }

			switch (type)
			{
				CASE(T_TENCENT_GET_USER_INFO);

				default:
				{
					return "T_UNKNOWN";
				}
				break;
			}

			return "T_UNKNOWN";
		}

	public :
		int16_t  _type;
};

struct RequestId
{
	RequestType _type;
	std::string _open_id;

	RequestId(RequestType type = RequestType::T_UNKNOWN, const std::string & oid = "")
		: _type(type), _open_id(oid)
	{
	}
};

inline bool operator == (const RequestId & lhs, const RequestId & rhs)
{
	return ((lhs._type == rhs._type) && (lhs._open_id == rhs._open_id));
}

inline bool operator != (const RequestId & lhs, const RequestId & rhs)
{
	return !(lhs == rhs);
}

inline bool operator < (const RequestId & lhs, const RequestId & rhs)
{
	return (lhs < rhs);
}

class Request
{
	public :
		Request()
			: _conn_id(),
			  _req()
		{
		}

		Request(const Request & other)
		{
			_conn_id        = other._conn_id;
			_req        = other._req;
			_timer      = other._timer;
		}

		Request & operator = (const Request & rhs)
		{
			if (&rhs == this)
			{
				return *this;
			}

			new (this) Request(rhs);
			return *this;
		}

		void set_timeout(int interval)
		{
			_timer.reset(interval, 1);
		}

		bool timeout()
		{
			return _timer();
		}

	public :
		ConnID             _conn_id;
		SSTencentPlatReq   _req;
		Timer              _timer;
};

class Response
{
	public :
		Response() {}

		Response(const Request & req)
		{
			_conn_id        = req._conn_id;
			_res._type      = req._req._type;
			_res._sequence  = req._req._sequence;
		}

		Response(const Response & other)
		{
			_conn_id  = other._conn_id;
			_res      = other._res;
		}

		Response & operator = (const Response & rhs)
		{
			if (&rhs == this)
			{
				return *this;
			}

			new (this) Response(rhs);

			return *this;
		}

	public :
		ConnID            _conn_id;
		SSTencentPlatRes  _res;
};

#endif

